home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / grapdrvs / x11drvs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-14  |  41.1 KB  |  1,080 lines

  1. /*****************************************************************************
  2. *   An X11 driver using only libx11.a.                         *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #ifdef __hpux
  8. typedef char *caddr_t;           /* Awful kludge. Let me know of a better way. */
  9. #endif /* __hpux */
  10.  
  11. #include <X11/Xlib.h>
  12. #include <X11/Xutil.h>
  13. #include <X11/cursorfont.h>
  14. #include <X11/Xresource.h>
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include <ctype.h>
  20.  
  21. #include "irit_sm.h"
  22. #include "genmat.h"
  23. #include "iritprsr.h"
  24. #include "allocate.h"
  25. #include "attribut.h"
  26. #include "ip_cnvrt.h"
  27. #include "cagd_lib.h"
  28. #include "symb_lib.h"
  29. #include "iritgrap.h"
  30. #include "x11drvs.h"
  31.  
  32. #define X11_FONT_NAME        "8x13"
  33.  
  34. #define RESOURCE_NAME        "irit"
  35.  
  36. #define DEFAULT_TRANS_WIDTH    200
  37. #define DEFAULT_TRANS_HEIGHT    500
  38. #define DEFAULT_VIEW_WIDTH    400
  39. #define DEFAULT_VIEW_HEIGHT    400
  40.  
  41. /* X global specific staff goes here: */
  42. int ViewHasSize = FALSE,
  43.     ViewHasPos = FALSE,
  44.     ViewPosX = 0,
  45.     ViewPosY = 0,
  46.     XScreen;
  47. unsigned int
  48.     MaxColors = IG_MAX_COLOR,
  49.     ViewBackGroundPixel,
  50.     ViewBorderPixel,
  51.     ViewTextPixel,
  52.     ViewBorderWidth = 1,
  53.     ViewWidth = DEFAULT_VIEW_WIDTH,
  54.     ViewHeight = DEFAULT_VIEW_HEIGHT;
  55. Colormap XColorMap;
  56. XColor BlackColor,
  57.     *ViewCursorColor = NULL;
  58. Display *XDisplay;
  59. Window XRoot, ViewWndw;
  60. GC XViewGraphContext;
  61.  
  62. static GC XTransGraphContext;
  63. static Visual *XVisual;
  64. static XFontStruct *XLoadedFont;
  65. static XColor
  66.     *TransCursorColor = NULL;
  67. static unsigned long
  68.     TransBackGroundPixel,
  69.     TransBorderPixel,
  70.     TransTextPixel,
  71.     TransSubWinBackPixel,
  72.     TransSubWinBorderPixel;
  73. static int
  74.     XFontYOffsetToCenter = 0,
  75.     TransHasSize = FALSE,
  76.     TransHasPos = FALSE,
  77.     TransPosX = 0,
  78.     TransPosY = 0;
  79. static unsigned int
  80.     TransBorderWidth = 1,
  81.     TransSubWinBorderWidth = 1,
  82.     TransWidth = DEFAULT_TRANS_WIDTH,
  83.     TransHeight = DEFAULT_TRANS_HEIGHT;
  84.  
  85. /* X Colors to be used for viewed object (see also iritgrap.h): */
  86. static int XViewColorDefs[IG_MAX_COLOR + 1][3] =
  87. {
  88.     {     0,     0,     0 },  /* 0. IG_IRIT_BLACK */
  89.     {     0,     0, 43350 },  /* 1. IG_IRIT_BLUE */
  90.     {     0, 43350,     0 },  /* 2. IG_IRIT_GREEN */
  91.     {     0, 43350, 43350 },  /* 3. IG_IRIT_CYAN */
  92.     { 43350,     0,     0 },  /* 4. IG_IRIT_RED */
  93.     { 43350,     0, 43350 },  /* 5. IG_IRIT_MAGENTA */
  94.     { 43350, 43350,     0 },  /* 6. IG_IRIT_BROWN */
  95.     { 43350, 43350, 43350 },  /* 7. IG_IRIT_LIGHTGREY */
  96.     { 21675, 21675, 21675 },  /* 8. IG_IRIT_DARKGRAY */
  97.     { 21675, 21675, 65535 },  /* 9. IG_IRIT_LIGHTBLUE */
  98.     { 21675, 65535, 21675 },  /* 10. IG_IRIT_LIGHTGREEN */
  99.     { 21675, 65535, 65535 },  /* 11. IG_IRIT_LIGHTCYAN */
  100.     { 65535, 21675, 21675 },  /* 12. IG_IRIT_LIGHTRED */
  101.     { 65535, 21675, 65535 },  /* 13. IG_IRIT_LIGHTMAGENTA */
  102.     { 65535, 65535, 21675 },  /* 14. IG_IRIT_YELLOW */
  103.     { 65535, 65535, 65535 }   /* 15. IG_IRIT_WHITE */
  104. };
  105. XColor XViewColorsHigh[IG_MAX_COLOR + 1];
  106. XColor XViewColorsLow[IG_MAX_COLOR + 1];
  107.  
  108. /* X transformation window staff goes here: */
  109. static Window TransformWndw;
  110. static Window ObjScrTglWndw;
  111. static Window PersOrthoTglWndw, PersOrthoZWndw;
  112. static Window RotateXWndw, RotateYWndw, RotateZWndw;
  113. static Window TranslateXWndw, TranslateYWndw, TranslateZWndw;
  114. static Window ScaleWndw;
  115. static Window DepthCueWndw;
  116. static Window AnimationWndw;
  117. static Window SaveMatrixWndw;
  118. static Window PushMatrixWndw;
  119. static Window PopMatrixWndw;
  120. static Window QuitWndw;
  121.  
  122. /* Viewing state variables: */
  123. static int
  124.     SubWindowWidthState2 = 1,
  125.     SubWindowHeightState2 = 1;
  126.  
  127. static char *ReadOneXDefault(char *Entry);
  128. static void ReadXDefaults(void);
  129. static void SetTransformWindow(int argc, char **argv);
  130. static void RedrawTransformWindow(void);
  131. static Window SetTransformSubWindow(int SubTransPosX,
  132.                     int SubTransPosY,
  133.                     unsigned int SubTransWidth,
  134.                     unsigned int SubTransHeight);
  135. static void RedrawTransformSubWindow(Window Win,
  136.                      int SubTransPosX,
  137.                      int SubTransPosY,
  138.                      unsigned int SubTransWidth,
  139.                      unsigned int SubTransHeight,
  140.                      int DrawMiddleVertLine,
  141.                      char *DrawString);
  142. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor);
  143. static void DrawText(Window Win,
  144.              char *Str,
  145.              int PosX,
  146.              int PosY,
  147.              unsigned long Color);
  148.  
  149. /*****************************************************************************
  150. * DESCRIPTION:                                                               M
  151. * Main module of x11drvs - X11 graphics driver of IRIT.                      M
  152. *                                                                            *
  153. * PARAMETERS:                                                                M
  154. *   argc, argv:  Command line.                                               M
  155. *                                                                            *
  156. * RETURN VALUE:                                                              M
  157. *   int:         Exit code.                                                  M
  158. *                                                                            *
  159. * KEYWORDS:                                                                  M
  160. *   WinMain                                                                  M
  161. *****************************************************************************/
  162. void main(int argc, char **argv)
  163. {
  164.     int i;
  165.     XGCValues values;
  166.     RealType ChangeFactor;
  167.     IGGraphicEventType Event;
  168.  
  169.     IGConfigureGlobals("x11drvs", argc, argv);
  170.  
  171.     /* Lets see if we can get access to the X server before we even start: */
  172.     if ((XDisplay = (Display *) XOpenDisplay(NULL)) == NULL) {
  173.     fprintf(stderr, "x11drvs: Failed to access X server, abored.\n");
  174.         exit(-1);
  175.     }
  176.     if ((XLoadedFont = XLoadQueryFont(XDisplay, X11_FONT_NAME)) == NULL) {
  177.     fprintf(stderr,
  178.         "x11drvs: Failed to load required X font \"%s\", aborted.\n",
  179.         X11_FONT_NAME);
  180.     exit(-1);
  181.     }
  182.     XFontYOffsetToCenter = (XLoadedFont -> ascent - XLoadedFont -> descent + 1)
  183.                                     / 2;
  184.  
  185.     XScreen = DefaultScreen(XDisplay);
  186.     XRoot = RootWindow(XDisplay, XScreen);
  187.     XColorMap = DefaultColormap(XDisplay, XScreen);
  188.     XVisual = DefaultVisual(XDisplay, XScreen);
  189.     values.foreground = WhitePixel(XDisplay, XScreen);
  190.     values.background = BlackPixel(XDisplay, XScreen);
  191.     values.font = XLoadedFont -> fid;
  192.     XTransGraphContext = XCreateGC(XDisplay, XRoot,
  193.                   GCForeground | GCBackground | GCFont, &values);
  194.     XViewGraphContext = XCreateGC(XDisplay, XRoot,
  195.                   GCForeground | GCBackground, &values);
  196.     
  197.     if (XDisplay->db == NULL)
  198.     XGetDefault(XDisplay, "", "");
  199.     ReadXDefaults();
  200.  
  201.     for (i = 0; i <= IG_MAX_COLOR; i++) {
  202.     XViewColorsHigh[i].red   = XViewColorDefs[i][0];
  203.     XViewColorsHigh[i].green = XViewColorDefs[i][1];
  204.     XViewColorsHigh[i].blue  = XViewColorDefs[i][2];
  205.  
  206.     /* If fails to allocate the color - take WHITE instead. */
  207.     if (!XAllocColor(XDisplay, XColorMap, &XViewColorsHigh[i]))
  208.         XViewColorsHigh[i].pixel = WhitePixel(XDisplay, XScreen);
  209.  
  210.     XViewColorsLow[i].red   = XViewColorDefs[i][0] / 2;
  211.     XViewColorsLow[i].green = XViewColorDefs[i][1] / 2;
  212.     XViewColorsLow[i].blue  = XViewColorDefs[i][2] / 2;
  213.  
  214.     /* If fails to allocate the color - take WHITE instead. */
  215.     if (!XAllocColor(XDisplay, XColorMap, &XViewColorsLow[i]))
  216.         XViewColorsLow[i].pixel = WhitePixel(XDisplay, XScreen);
  217.     }
  218.  
  219.     values.line_width = IGGlblLineWidth;
  220.     XChangeGC(XDisplay, XViewGraphContext, GCLineWidth, &values);
  221.  
  222.     IGCreateStateMenu();
  223.  
  224.     SetTransformWindow(argc, argv);
  225.     SetViewWindow(argc, argv);
  226.  
  227.     sleep(1); /* Some systems get confused if we draw immediately. */
  228.  
  229.     XFlush(XDisplay);
  230.  
  231.     while ((Event = GetGraphicEvent(&ChangeFactor)) != IG_EVENT_QUIT) {
  232.     if (IGProcessEvent(Event, ChangeFactor * IGGlblChangeFactor))
  233.         IGRedrawViewWindow();
  234.     }
  235.  
  236.     XFreeGC(XDisplay, XViewGraphContext);
  237.     XFreeGC(XDisplay, XTransGraphContext);
  238.     XUnloadFont(XDisplay, XLoadedFont -> fid);
  239.     XCloseDisplay(XDisplay);
  240. }
  241.  
  242. /*****************************************************************************
  243. * DESCRIPTION:                                                               M
  244. * Optionally construct a state pop up menu for the driver, if has one.       M
  245. *                                                                            *
  246. * PARAMETERS:                                                                M
  247. *   None                                                                     *
  248. *                                                                            *
  249. * RETURN VALUE:                                                              M
  250. *   void                                                                     M
  251. *                                                                            *
  252. * KEYWORDS:                                                                  M
  253. *   IGCreateStateMenu                                                        M
  254. *****************************************************************************/
  255. void IGCreateStateMenu(void)
  256. {
  257. }
  258.  
  259. /*****************************************************************************
  260. * DESCRIPTION:                                                               *
  261. * Reads one default from X resource data base.                     *
  262. *                                                                            *
  263. * PARAMETERS:                                                                *
  264. *   Entry:    String name of the defau;t to read.                            *
  265. *                                                                            *
  266. * RETURN VALUE:                                                              *
  267. *   char *:   Value f found, NULL otherwise.                                 *
  268. *****************************************************************************/
  269. static char *ReadOneXDefault(char *Entry)
  270. {
  271.     XrmString Type;
  272.     XrmValue Result;
  273.     char Line[LINE_LEN_LONG];
  274.  
  275.     sprintf(Line, "%s.%s", RESOURCE_NAME, Entry);
  276.     if ( XrmGetResource(XDisplay->db, Line, "Program.Name", &Type, &Result ) )
  277.     return Result.addr;
  278.     else
  279.     return NULL;
  280. }
  281.  
  282. /*****************************************************************************
  283. * DESCRIPTION:                                                               *
  284. * Reads Defaults from X data base.                         *
  285. *                                                                            *
  286. * PARAMETERS:                                                                *
  287. *   None                                                                     *
  288. *                                                                            *
  289. * RETURN VALUE:                                                              *
  290. *   void                                                                     *
  291. *****************************************************************************/
  292. static void ReadXDefaults(void)
  293. {
  294.     int i;
  295.     XColor Color;
  296.     char *TransBackGroundColor = ReadOneXDefault("Trans.BackGround"),
  297.          *TransBorderColor = ReadOneXDefault("Trans*BorderColor"),
  298.          *TransBorderWidthStr = ReadOneXDefault("Trans*BorderWidth"),
  299.          *TransTextColor = ReadOneXDefault("Trans.TextColor"),
  300.          *TransSubWinBackColor = ReadOneXDefault("Trans.SubWin.BackGround"),
  301.          *TransSubWinBorderColor = ReadOneXDefault("Trans.SubWin.BorderColor"),
  302.          *TransSubWinBorderWidthStr = ReadOneXDefault("Trans.SubWin.BorderWidth"),
  303.          *TransGeometry = ReadOneXDefault("Trans.Geometry"),
  304.          *TransCursorColorStr = ReadOneXDefault("Trans.CursorColor"),
  305.          *ViewBackGroundColor = ReadOneXDefault("View.BackGround"),
  306.          *ViewTextColor = ReadOneXDefault("View.TextColor"),
  307.          *ViewBorderColor = ReadOneXDefault("View.BorderColor"),
  308.          *ViewBorderWidthStr = ReadOneXDefault("View.BorderWidth"),
  309.          *ViewGeometry = ReadOneXDefault("View.Geometry"),
  310.          *ViewCursorColorStr = ReadOneXDefault("View.CursorColor"),
  311.          *MaxColorsStr = ReadOneXDefault("MaxColors");
  312.  
  313.     if (XParseColor(XDisplay, XColorMap, "Black", &BlackColor))
  314.     XAllocColor(XDisplay, XColorMap, &BlackColor);
  315.  
  316.     if (TransBackGroundColor != NULL &&
  317.     XParseColor(XDisplay, XColorMap, TransBackGroundColor, &Color) &&
  318.     XAllocColor(XDisplay, XColorMap, &Color))
  319.     TransBackGroundPixel = Color.pixel;
  320.     else
  321.     TransBackGroundPixel = BlackPixel(XDisplay, XScreen);
  322.  
  323.     if (TransBorderColor != NULL &&
  324.     XParseColor(XDisplay, XColorMap, TransBorderColor, &Color) &&
  325.     XAllocColor(XDisplay, XColorMap, &Color))
  326.     TransBorderPixel = Color.pixel;
  327.     else
  328.     TransBorderPixel = WhitePixel(XDisplay, XScreen);
  329.  
  330.     if (TransBorderWidthStr)
  331.     TransBorderWidth = atoi(TransBorderWidthStr);
  332.     else
  333.     TransBorderWidth = 1;
  334.  
  335.     if (TransTextColor != NULL &&
  336.     XParseColor(XDisplay, XColorMap, TransTextColor, &Color) &&
  337.     XAllocColor(XDisplay, XColorMap, &Color))
  338.     TransTextPixel = Color.pixel;
  339.     else
  340.     TransTextPixel = WhitePixel(XDisplay, XScreen);
  341.  
  342.     if (TransSubWinBackColor != NULL &&
  343.     XParseColor(XDisplay, XColorMap, TransSubWinBackColor, &Color) &&
  344.     XAllocColor(XDisplay, XColorMap, &Color))
  345.     TransSubWinBackPixel = Color.pixel;
  346.     else
  347.     TransSubWinBackPixel = BlackPixel(XDisplay, XScreen);
  348.  
  349.     if (TransSubWinBorderColor != NULL &&
  350.     XParseColor(XDisplay, XColorMap, TransSubWinBorderColor, &Color) &&
  351.     XAllocColor(XDisplay, XColorMap, &Color))
  352.     TransSubWinBorderPixel = Color.pixel;
  353.     else
  354.     TransSubWinBorderPixel = WhitePixel(XDisplay, XScreen);
  355.  
  356.     if (TransSubWinBorderWidthStr)
  357.     TransSubWinBorderWidth = atoi(TransSubWinBorderWidthStr);
  358.     else
  359.     TransSubWinBorderWidth = 1;
  360.  
  361.     if (IGGlblTransPrefPos &&
  362.     sscanf(IGGlblTransPrefPos, "%d,%d,%d,%d",
  363.            &TransPosX, &TransWidth, &TransPosY, &TransHeight) == 4) {
  364.     TransWidth -= TransPosX;
  365.     TransHeight -= TransPosY;
  366.     TransHasSize = TransHasPos = TRUE;
  367.     }
  368.     else if ((IGGlblTransPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
  369.          TransGeometry) {
  370.     i = XParseGeometry(TransGeometry, &TransPosX, &TransPosY,
  371.                                   &TransWidth, &TransHeight);
  372.     TransHasPos = i & XValue && i & YValue;
  373.     TransHasSize =  i & WidthValue && i & HeightValue;
  374.     }
  375.     else
  376.         TransHasSize = TransHasPos = FALSE;
  377.  
  378.     if (TransCursorColorStr != NULL &&
  379.     XParseColor(XDisplay, XColorMap, TransCursorColorStr, &Color) &&
  380.     XAllocColor(XDisplay, XColorMap, &Color)) {
  381.     TransCursorColor = (XColor *) IritMalloc(sizeof(XColor));
  382.     *TransCursorColor = Color;
  383.     }
  384.     else
  385.     TransCursorColor = NULL;
  386.  
  387.     if (ViewBackGroundColor &&
  388.     XParseColor(XDisplay, XColorMap, ViewBackGroundColor, &Color) &&
  389.     XAllocColor(XDisplay, XColorMap, &Color))
  390.     ViewBackGroundPixel = Color.pixel;
  391.     else
  392.     ViewBackGroundPixel = BlackPixel(XDisplay, XScreen);
  393.  
  394.     if (ViewBorderColor &&
  395.     XParseColor(XDisplay, XColorMap, ViewBorderColor, &Color) &&
  396.     XAllocColor(XDisplay, XColorMap, &Color))
  397.     ViewBorderPixel = Color.pixel;
  398.     else
  399.     ViewBorderPixel = WhitePixel(XDisplay, XScreen);
  400.  
  401.     if (ViewTextColor != NULL &&
  402.     XParseColor(XDisplay, XColorMap, ViewTextColor, &Color) &&
  403.     XAllocColor(XDisplay, XColorMap, &Color))
  404.     ViewTextPixel = Color.pixel;
  405.     else
  406.     ViewTextPixel = WhitePixel(XDisplay, XScreen);
  407.  
  408.     if (ViewBorderWidthStr)
  409.     ViewBorderWidth = atoi(ViewBorderWidthStr);
  410.     else
  411.     ViewBorderWidth = 1;
  412.  
  413.     if (IGGlblViewPrefPos &&
  414.     sscanf(IGGlblViewPrefPos, "%d,%d,%d,%d",
  415.            &ViewPosX, &ViewWidth, &ViewPosY, &ViewHeight) == 4) {
  416.     ViewWidth -= ViewPosX;
  417.     ViewHeight -= ViewPosY;
  418.     ViewHasSize = ViewHasPos = TRUE;
  419.     }
  420.     else if ((IGGlblViewPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
  421.          ViewGeometry) {
  422.     i = XParseGeometry(ViewGeometry, &ViewPosX, &ViewPosY,
  423.                                  &ViewWidth, &ViewHeight);
  424.     ViewHasPos = i & XValue && i & YValue;
  425.     ViewHasSize = i & WidthValue && i & HeightValue;
  426.     }
  427.     else
  428.     ViewHasSize = ViewHasPos = FALSE;
  429.  
  430.     if (ViewCursorColorStr != NULL &&
  431.     XParseColor(XDisplay, XColorMap, ViewCursorColorStr, &Color) &&
  432.     XAllocColor(XDisplay, XColorMap, &Color)) {
  433.     ViewCursorColor = (XColor *) IritMalloc(sizeof(XColor));
  434.     *ViewCursorColor = Color;
  435.     }
  436.     else
  437.     ViewCursorColor = NULL;
  438.  
  439.     if (MaxColorsStr)
  440.     MaxColors = atoi(MaxColorsStr);
  441.     else
  442.     MaxColors = IG_MAX_COLOR;
  443.  
  444. }
  445.  
  446. /*****************************************************************************
  447. * DESCRIPTION:                                                               *
  448. * Sets up and draw a transformation window.                     *
  449. *                                                                            *
  450. * PARAMETERS:                                                                *
  451. *   argc, argv:   Command line.                             *
  452. *                                                                            *
  453. * RETURN VALUE:                                                              *
  454. *   void                                                                     *
  455. *****************************************************************************/
  456. static void SetTransformWindow(int argc, char **argv)
  457. {
  458.     int SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
  459.     long ValueMask;
  460.     XSizeHints Hints;
  461.     XSetWindowAttributes SetWinAttr;
  462.  
  463.     SetWinAttr.background_pixel = TransBackGroundPixel;
  464.     SetWinAttr.border_pixel = TransBorderPixel;
  465.     ValueMask = CWBackPixel | CWBorderPixel;
  466.  
  467.     Hints.flags = PMinSize | PMaxSize;
  468.     Hints.x = Hints.y = 1;
  469.     Hints.min_width = 100;
  470.     Hints.max_width = 2000;
  471.     Hints.min_height = 200;
  472.     Hints.max_height = 2000;
  473.     if (TransHasSize) {
  474.     Hints.flags |= PSize;
  475.     if (TransWidth < Hints.min_width)
  476.         TransWidth = Hints.min_width;
  477.     if (TransWidth > Hints.max_width)
  478.         TransWidth = Hints.max_width;
  479.     if (TransHeight < Hints.min_height)
  480.         TransHeight = Hints.min_height;
  481.     if (TransHeight > Hints.max_height)
  482.         TransHeight = Hints.max_height;
  483.     Hints.width = TransWidth;
  484.     Hints.height = TransHeight;
  485.     }
  486.     else {
  487.     Hints.flags |= PSize;
  488.     Hints.width = TransWidth = DEFAULT_TRANS_WIDTH;
  489.     Hints.height = TransHeight = DEFAULT_TRANS_HEIGHT;
  490.     }
  491.     if (TransHasPos) {
  492.     Hints.flags |= USPosition;
  493.     Hints.x = TransPosX;
  494.     Hints.y = TransPosY;
  495.     }
  496.  
  497.     TransformWndw = XCreateWindow(XDisplay, XRoot,
  498.                   TransPosX, TransPosY,
  499.                   TransWidth, TransHeight,
  500.                       1, 0, CopyFromParent, CopyFromParent,
  501.                       ValueMask, &SetWinAttr);
  502.  
  503.     XSetStandardProperties(XDisplay, TransformWndw,
  504.                RESOURCE_NAME, RESOURCE_NAME, None,
  505.                argv, argc,
  506.                &Hints);
  507.  
  508.     /* Now create the sub windows inside. Note we do not place them yet. */
  509.     SubTransPosX = 0;
  510.     SubTransPosY = TransHeight;
  511.     SubTransWidth = TransWidth - SubTransPosX * 2;
  512.     SubTransHeight = TransHeight / 25;
  513.  
  514.     /* OBJECT/SCREEN space toggle: */
  515.     ObjScrTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  516.                       SubTransWidth, SubTransHeight);
  517.  
  518.     /* PERSPECTIVE/ORTHOGRPHIC toggle: */
  519.     PersOrthoTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  520.                          SubTransWidth, SubTransHeight);
  521.     PersOrthoZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  522.                          SubTransWidth, SubTransHeight);
  523.  
  524.     /* ROTATE: */
  525.     RotateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  526.                     SubTransWidth, SubTransHeight);
  527.     RotateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  528.                     SubTransWidth, SubTransHeight);
  529.     RotateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  530.                     SubTransWidth, SubTransHeight);
  531.     /* TRANSLATE: */
  532.     TranslateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  533.                        SubTransWidth, SubTransHeight);
  534.     TranslateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  535.                        SubTransWidth, SubTransHeight);
  536.     TranslateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  537.                        SubTransWidth, SubTransHeight);
  538.     /* SCALE: */
  539.     ScaleWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  540.                       SubTransWidth, SubTransHeight);
  541.  
  542.     /* DEPTH CUE: */
  543.     DepthCueWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  544.                      SubTransWidth, SubTransHeight);
  545.  
  546.     /* ANIMATION: */
  547.     AnimationWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  548.                       SubTransWidth, SubTransHeight);
  549.  
  550.     /* SAVE MATRIX: */
  551.     SaveMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  552.                        SubTransWidth, SubTransHeight);
  553.  
  554.     /* PUSH MATRIX: */
  555.     PushMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  556.                        SubTransWidth, SubTransHeight);
  557.  
  558.     /* POP MATRIX: */
  559.     PopMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  560.                       SubTransWidth, SubTransHeight);
  561.  
  562.     /* QUIT: */
  563.     QuitWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  564.                      SubTransWidth, SubTransHeight);
  565.  
  566.     XSelectInput(XDisplay, TransformWndw, ExposureMask);
  567. }
  568.  
  569. /*****************************************************************************
  570. * DESCRIPTION:                                                               M
  571. * Redraws the transformation window.                         M
  572. *                                                                            *
  573. * PARAMETERS:                                                                M
  574. *   None                                                                     M
  575. *                                                                            *
  576. * RETURN VALUE:                                                              M
  577. *   void                                                                     M
  578. *                                                                            *
  579. * KEYWORDS:                                                                  M
  580. *   RedrawTransformWindow                                                    M
  581. *****************************************************************************/
  582. static void RedrawTransformWindow(void)
  583. {
  584.     int SubTransPosX, SubTransPosY,
  585.         SizeChanged = FALSE;
  586.     unsigned long SubTransWidth, SubTransHeight;
  587.     XWindowAttributes TransWindowAttr;
  588.  
  589.     XClearWindow(XDisplay, TransformWndw);
  590.  
  591.     /* Get the window attributes, and see if it is the same size or not. */
  592.     XGetWindowAttributes(XDisplay, TransformWndw, &TransWindowAttr);
  593.     if (TransWindowAttr.width != TransWidth ||
  594.     TransWindowAttr.height != TransHeight) {
  595.     SizeChanged = TRUE;
  596.     TransWidth = TransWindowAttr.width;
  597.     TransHeight = TransWindowAttr.height;
  598.     }
  599.  
  600.     /* Now lets update the sub windows inside: */
  601.     SubTransPosX = MIN(TransWidth / 10, 20);
  602.     SubTransPosY =  TransHeight / 30;
  603.     SubTransWidth = TransWidth - SubTransPosX * 2;
  604.     SubTransHeight = TransHeight / 30;
  605.  
  606.     /* OBJECT/SCREEN space toggle: */
  607.     RedrawTransformSubWindow(ObjScrTglWndw, SubTransPosX, SubTransPosY,
  608.                  SubTransWidth, SubTransHeight, FALSE,
  609.                  IGGlblTransformMode == IG_TRANS_OBJECT ?
  610.                  "Object" : "Screen");
  611.     SubTransPosY += SubTransHeight * 2;
  612.  
  613.     /* PERSPECTIVE/ORTHOGRAPHIC toggle: */
  614.     RedrawTransformSubWindow(PersOrthoTglWndw, SubTransPosX, SubTransPosY,
  615.                  SubTransWidth, SubTransHeight, FALSE,
  616.                  IGGlblViewMode == IG_VIEW_ORTHOGRAPHIC ?
  617.                  "Orthographic" : "Perspective");
  618.     SubTransPosY += SubTransHeight;
  619.     RedrawTransformSubWindow(PersOrthoZWndw, SubTransPosX, SubTransPosY,
  620.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  621.     SubTransPosY += SubTransHeight;
  622.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  623.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  624.     SubTransPosY += SubTransHeight;
  625.  
  626.     /* ROTATE: */
  627.     DrawText(TransformWndw, "Rotate", TransWidth / 2, SubTransPosY,
  628.          TransTextPixel);
  629.     SubTransPosY += SubTransHeight / 2;
  630.     RedrawTransformSubWindow(RotateXWndw, SubTransPosX, SubTransPosY,
  631.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  632.     SubTransPosY += SubTransHeight;
  633.     DrawText(TransformWndw, "X", SubTransPosX / 2,
  634.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  635.     RedrawTransformSubWindow(RotateYWndw, SubTransPosX, SubTransPosY,
  636.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  637.     SubTransPosY += SubTransHeight;
  638.     DrawText(TransformWndw, "Y", SubTransPosX / 2,
  639.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  640.     RedrawTransformSubWindow(RotateZWndw, SubTransPosX, SubTransPosY,
  641.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  642.     SubTransPosY += SubTransHeight;
  643.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  644.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  645.  
  646.     /* TRANSLATE: */
  647.     SubTransPosY += SubTransHeight;
  648.     DrawText(TransformWndw, "Translate", TransWidth / 2, SubTransPosY,
  649.          TransTextPixel);
  650.     SubTransPosY += SubTransHeight / 2;
  651.     RedrawTransformSubWindow(TranslateXWndw, SubTransPosX, SubTransPosY,
  652.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  653.     SubTransPosY += SubTransHeight;
  654.     DrawText(TransformWndw, "X", SubTransPosX / 2,
  655.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  656.     RedrawTransformSubWindow(TranslateYWndw, SubTransPosX, SubTransPosY,
  657.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  658.     SubTransPosY += SubTransHeight;
  659.     DrawText(TransformWndw, "Y", SubTransPosX / 2,
  660.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  661.     RedrawTransformSubWindow(TranslateZWndw, SubTransPosX, SubTransPosY,
  662.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  663.     SubTransPosY += SubTransHeight;
  664.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  665.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  666.  
  667.     /* SCALE: */
  668.     SubTransPosY += SubTransHeight;
  669.     DrawText(TransformWndw, "Scale", TransWidth / 2, SubTransPosY,
  670.          TransTextPixel);
  671.     SubTransPosY += SubTransHeight / 2;
  672.     RedrawTransformSubWindow(ScaleWndw, SubTransPosX, SubTransPosY,
  673.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  674.  
  675.     /* DEPTH CUE: */
  676.     SubTransPosY += SubTransHeight * 2;
  677.     RedrawTransformSubWindow(DepthCueWndw, SubTransPosX, SubTransPosY,
  678.                  SubTransWidth, SubTransHeight, FALSE,
  679.                  IGGlblDepthCue ? "Depth Cue" : "No Depth Cue");
  680.  
  681.     /* ANIMATION: */
  682.     SubTransPosY += SubTransHeight * 2;
  683.     RedrawTransformSubWindow(AnimationWndw, SubTransPosX, SubTransPosY,
  684.                  SubTransWidth, SubTransHeight, FALSE,
  685.                  "Animation");
  686.  
  687.     /* SAVE MATRIX: */
  688.     SubTransPosY += SubTransHeight * 2;
  689.     RedrawTransformSubWindow(SaveMatrixWndw, SubTransPosX, SubTransPosY,
  690.                  SubTransWidth, SubTransHeight, FALSE,
  691.                  "Save Matrix");
  692.  
  693.     /* PUSH MATRIX: */
  694.     SubTransPosY += SubTransHeight + SubTransHeight / 2;
  695.     RedrawTransformSubWindow(PushMatrixWndw, SubTransPosX, SubTransPosY,
  696.                  SubTransWidth, SubTransHeight, FALSE,
  697.                  "Push Matrix");
  698.  
  699.     /* POP MATRIX: */
  700.     SubTransPosY += SubTransHeight + SubTransHeight / 2;
  701.     RedrawTransformSubWindow(PopMatrixWndw, SubTransPosX, SubTransPosY,
  702.                  SubTransWidth, SubTransHeight, FALSE,
  703.                  "Pop Matrix");
  704.  
  705.     /* QUIT: */
  706.     SubTransPosY += SubTransHeight * 3;
  707.     RedrawTransformSubWindow(QuitWndw, SubTransPosX, SubTransPosY,
  708.                  SubTransWidth, SubTransHeight, FALSE, "Quit" );
  709.  
  710.     /* Save half of the window width so we can refer to the zero point on X */
  711.     /* axes, which is the vertical line in the middle of the window:        */
  712.     SubWindowWidthState2 = SubTransWidth / 2;
  713.     SubWindowHeightState2 = SubTransHeight / 2;
  714.  
  715.     XFlush(XDisplay);
  716. }
  717.  
  718. /*****************************************************************************
  719. * DESCRIPTION:                                                               *
  720. * Sets up a transformation sub window.                         *
  721. *                                                                            *
  722. * PARAMETERS:                                                                *
  723. *   SubTransPosX, SubTransPosY:      Location of the subwindows.         *
  724. *   SubTransWidth, SubTransHeight:   Dimensions of the subwindow.         *
  725. *                                                                            *
  726. * RETURN VALUE:                                                              *
  727. *   Window:      Handle on constructed window.                               *
  728. *****************************************************************************/
  729. static Window SetTransformSubWindow(int SubTransPosX,
  730.                     int SubTransPosY,
  731.                     unsigned int SubTransWidth,
  732.                     unsigned int SubTransHeight)
  733. {
  734.     long ValueMask;
  735.     XSetWindowAttributes SetWinAttr;
  736.     Window Win;
  737.  
  738.     SetWinAttr.background_pixel = TransSubWinBackPixel;
  739.     SetWinAttr.border_pixel = TransSubWinBorderPixel;
  740.     SetWinAttr.bit_gravity = SetWinAttr.win_gravity = CenterGravity;
  741.     ValueMask = CWBackPixel | CWBorderPixel | CWBitGravity | CWWinGravity;
  742.  
  743.     Win = XCreateWindow(XDisplay, TransformWndw,
  744.             SubTransPosX, SubTransPosY,
  745.             SubTransWidth, SubTransHeight,
  746.             1, 0, CopyFromParent, CopyFromParent,
  747.             ValueMask, &SetWinAttr);
  748.  
  749.     XSelectInput(XDisplay, Win, ButtonPressMask | Button1MotionMask);
  750.  
  751.     XMapWindow(XDisplay, Win);
  752.  
  753.     return Win;
  754. }
  755.  
  756. /*****************************************************************************
  757. * DESCRIPTION:                                                               *
  758. * Redraws a transformation sub window.                         *
  759. *                                                                            *
  760. * PARAMETERS:                                                                *
  761. *   Win:                 A handle on transformation window.      *
  762. *   SubTransPosX, SubTransPosY:      Location of the subwindows.         *
  763. *   SubTransWidth, SubTransHeight:   Dimensions of the subwindow.         *
  764. *   DrawMiddleVertLine:              Do we need a vertical middle line?      *
  765. *   DrawString:                      Any string to draw inside?              *
  766. *                                                                            *
  767. * RETURN VALUE:                                                              *
  768. *   void                                                                     *
  769. *****************************************************************************/
  770. static void RedrawTransformSubWindow(Window Win,
  771.                      int SubTransPosX,
  772.                      int SubTransPosY,
  773.                      unsigned int SubTransWidth,
  774.                      unsigned int SubTransHeight,
  775.                      int DrawMiddleVertLine,
  776.                      char *DrawString)
  777. {
  778.     XGCValues values;
  779.  
  780.     XMoveResizeWindow(XDisplay, Win, SubTransPosX, SubTransPosY,
  781.                                        SubTransWidth, SubTransHeight);
  782.     if (DrawMiddleVertLine) {
  783.     values.foreground = TransSubWinBorderPixel;
  784.     XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
  785.  
  786.     XDrawLine(XDisplay, Win, XTransGraphContext,
  787.           SubTransWidth / 2, 0, SubTransWidth / 2, SubTransHeight);
  788.     }
  789.     if (DrawString != NULL) {
  790.     DrawText(Win, DrawString, SubTransWidth / 2, SubTransHeight / 2,
  791.          TransTextPixel);
  792.     }
  793. }
  794.  
  795. /*****************************************************************************
  796. * DESCRIPTION:                                                               *
  797. * Handles input events                                                       *
  798. *                                                                            *
  799. * PARAMETERS:                                                                *
  800. *   ChangeFactor:        A continuous numeric value between -1 and 1. This   *
  801. *             value will be used to set amount of event such as   *
  802. *             rotation or translation.                 *
  803. *                                                                            *
  804. * RETURN VALUE:                                                              *
  805. *   IGGraphicEventType:  Type of new event.                                  *
  806. *****************************************************************************/
  807. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor)
  808. {
  809.     static int LastX;
  810.     XEvent Event;
  811.     XWindowAttributes WinAttr;
  812.  
  813.     XMapWindow(XDisplay, TransformWndw);
  814.  
  815.     while (TRUE) {
  816.     /* Maybe we have something in communication socket. */
  817.     if (!IGGlblStandAlone &&
  818.         IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
  819.         IGRedrawViewWindow();
  820.  
  821.     if (XPending(XDisplay)) {
  822.         XNextEvent(XDisplay, &Event);
  823.  
  824.         switch (Event.type) {
  825.         case Expose:
  826.                 /* Get rid of all Expose events in the queue. */
  827.                 while (XCheckWindowEvent(XDisplay, Event.xbutton.window,
  828.                          ExposureMask, &Event));
  829.             if (Event.xbutton.window == TransformWndw)
  830.             RedrawTransformWindow();
  831.             else if (Event.xbutton.window == ViewWndw) {
  832.             XGetWindowAttributes(XDisplay, ViewWndw, &WinAttr);
  833.             ViewWidth = WinAttr.width;
  834.             ViewHeight = WinAttr.height;
  835.             IGRedrawViewWindow();
  836.             }
  837.             break;
  838.         case ButtonPress:
  839.             LastX = Event.xbutton.x;
  840.             *ChangeFactor =
  841.             ((RealType) (LastX - SubWindowWidthState2)) /
  842.                          SubWindowWidthState2;
  843.  
  844.             if (Event.xbutton.window == ObjScrTglWndw) {
  845.             XClearWindow(XDisplay, ObjScrTglWndw);
  846.             IGGlblTransformMode =
  847.                 IGGlblTransformMode == IG_TRANS_OBJECT ?
  848.                            IG_TRANS_SCREEN :
  849.                            IG_TRANS_OBJECT;
  850.             DrawText(ObjScrTglWndw,
  851.                 IGGlblTransformMode == IG_TRANS_OBJECT ? "Object" :
  852.                                      "Screen",
  853.                 SubWindowWidthState2, SubWindowHeightState2,
  854.                 TransTextPixel);
  855.             return IG_EVENT_SCR_OBJ_TGL;
  856.             }
  857.             else if (Event.xbutton.window == PersOrthoTglWndw) {
  858.             XClearWindow(XDisplay, PersOrthoTglWndw);
  859.             IGGlblViewMode =
  860.                 IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  861.                           IG_VIEW_ORTHOGRAPHIC :
  862.                           IG_VIEW_PERSPECTIVE;
  863.             DrawText(PersOrthoTglWndw,
  864.                  IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  865.                      "Perspective" : "Orthographic",
  866.                  SubWindowWidthState2, SubWindowHeightState2,
  867.                  TransTextPixel);
  868.             return IG_EVENT_PERS_ORTHO_TGL;
  869.             }
  870.             else if (Event.xbutton.window == PersOrthoZWndw) {
  871.             return IG_EVENT_PERS_ORTHO_Z;
  872.             }
  873.             else if (Event.xbutton.window == RotateXWndw) {
  874.             return IG_EVENT_ROTATE_X;
  875.             }
  876.             else if (Event.xbutton.window == RotateYWndw) {
  877.             return IG_EVENT_ROTATE_Y;
  878.             }
  879.             else if (Event.xbutton.window == RotateZWndw) {
  880.             return IG_EVENT_ROTATE_Z;
  881.             }
  882.             else if (Event.xbutton.window == TranslateXWndw) {
  883.             return IG_EVENT_TRANSLATE_X;
  884.             }
  885.             else if (Event.xbutton.window == TranslateYWndw) {
  886.             return IG_EVENT_TRANSLATE_Y;
  887.             }
  888.             else if (Event.xbutton.window == TranslateZWndw) {
  889.             return IG_EVENT_TRANSLATE_Z;
  890.             }
  891.             else if (Event.xbutton.window == ScaleWndw) {
  892.             return IG_EVENT_SCALE;
  893.             }
  894.             else if (Event.xbutton.window == DepthCueWndw) {
  895.             XClearWindow(XDisplay, DepthCueWndw);
  896.             IGGlblDepthCue = !IGGlblDepthCue;
  897.             DrawText(DepthCueWndw,
  898.                  IGGlblDepthCue ? "Depth Cue" : "No Depth Cue",
  899.                  SubWindowWidthState2, SubWindowHeightState2,
  900.                  TransTextPixel);
  901.             return IG_EVENT_DEPTH_CUE;
  902.             }
  903.             else if (Event.xbutton.window == AnimationWndw) { 
  904.             XClearWindow(XDisplay, AnimationWndw);
  905.             DrawText(AnimationWndw, "Animation",
  906.                  SubWindowWidthState2, SubWindowHeightState2,
  907.                  TransTextPixel);
  908.             return IG_EVENT_ANIMATION;
  909.                     }
  910.             else if (Event.xbutton.window == SaveMatrixWndw) {
  911.             return IG_EVENT_SAVE_MATRIX;
  912.             }
  913.             else if (Event.xbutton.window == PushMatrixWndw) {
  914.             return IG_EVENT_PUSH_MATRIX;
  915.             }
  916.             else if (Event.xbutton.window == PopMatrixWndw) {
  917.             return IG_EVENT_POP_MATRIX;
  918.             }
  919.             else if (Event.xbutton.window == QuitWndw) {
  920.             XFlush(XDisplay);
  921.             return IG_EVENT_QUIT;
  922.             }
  923.             break;
  924.         case MotionNotify:
  925.             /* We may get events of movement in Y which are ignored. */
  926.             if (Event.xbutton.x - LastX == 0)
  927.             break;
  928.  
  929.             *ChangeFactor = ((RealType) (Event.xbutton.x - LastX)) /
  930.                             SubWindowWidthState2;
  931.             LastX = Event.xbutton.x;
  932.  
  933.             if (Event.xbutton.window == PersOrthoZWndw) {
  934.             return IG_EVENT_PERS_ORTHO_Z;
  935.             }
  936.             else if (Event.xbutton.window == RotateXWndw) {
  937.             return IG_EVENT_ROTATE_X;
  938.             }
  939.             else if (Event.xbutton.window == RotateYWndw) {
  940.             return IG_EVENT_ROTATE_Y;
  941.             }
  942.             else if (Event.xbutton.window == RotateZWndw) {
  943.             return IG_EVENT_ROTATE_Z;
  944.             }
  945.             else if (Event.xbutton.window == TranslateXWndw) {
  946.             return IG_EVENT_TRANSLATE_X;
  947.             }
  948.             else if (Event.xbutton.window == TranslateYWndw) {
  949.             return IG_EVENT_TRANSLATE_Y;
  950.             }
  951.             else if (Event.xbutton.window == TranslateZWndw) {
  952.             return IG_EVENT_TRANSLATE_Z;
  953.             }
  954.             else if (Event.xbutton.window == ScaleWndw) {
  955.             return IG_EVENT_SCALE;
  956.             }
  957.             break;
  958.         default:
  959.             fprintf(stderr,
  960.                 "x11drvs: undefined event type %d.\n", Event.type);
  961.         }
  962.     }
  963.     IritSleep(10);
  964.     }
  965. }
  966.  
  967. /*****************************************************************************
  968. * DESCRIPTION:                                                               M
  969. * Handles the events of the pop up window.                                   M
  970. *                                                                            *
  971. * PARAMETERS:                                                                M
  972. *   State:      Event to handle.                                             M
  973. *   Refresh:    Do we need to refresh the screen according to what we know   M
  974. *        on entry.                             M
  975. *                                                                            *
  976. * RETURN VALUE:                                                              M
  977. *   int:        TRUE, if we need to refresh the screen.                      M
  978. *                                                                            *
  979. * KEYWORDS:                                                                  M
  980. *   IGHandleState                                                            M
  981. *****************************************************************************/
  982. int IGHandleState(int State, int Refresh)
  983. {
  984.     int UpdateView = TRUE;
  985.  
  986.     switch (State) {
  987.     case IG_STATE_DEPTH_CUE:
  988.         XClearWindow(XDisplay, DepthCueWndw);
  989.         IGGlblDepthCue = !IGGlblDepthCue;
  990.         DrawText(DepthCueWndw,
  991.              IGGlblDepthCue ? "Depth Cue" : "No Depth Cue",
  992.              SubWindowWidthState2, SubWindowHeightState2,
  993.              TransTextPixel);
  994.  
  995.         break;
  996.     case IG_STATE_DOUBLE_BUFFER:
  997.         IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
  998.         break;
  999.     default:
  1000.         UpdateView = IGDefaultStateHandler(State, Refresh);
  1001.         break;
  1002.     }
  1003.  
  1004.     IGCreateStateMenu();
  1005.  
  1006.     return UpdateView;
  1007. }
  1008.  
  1009. /*****************************************************************************
  1010. * DESCRIPTION:                                                               *
  1011. * Draws text centered at the given position.                     *
  1012. *                                                                            *
  1013. * PARAMETERS:                                                                *
  1014. *   Win:        A handle on window to draw on.                               *
  1015. *   Str:        String to draw.                                              *
  1016. *   PosX, PosY: Location to draw at.                                         *
  1017. *   Color:      Of drawn text.                                               *
  1018. *                                                                            *
  1019. * RETURN VALUE:                                                              *
  1020. *   void                                                                     *
  1021. *****************************************************************************/
  1022. static void DrawText(Window Win,
  1023.              char *Str,
  1024.              int PosX,
  1025.              int PosY,
  1026.              unsigned long Color)
  1027. {
  1028.     int Len = strlen(Str),
  1029.         Width = XTextWidth(XLoadedFont, Str, Len);
  1030.     XGCValues values;
  1031.  
  1032.     values.foreground = Color;
  1033.     XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
  1034.  
  1035.     XDrawString(XDisplay, Win, XTransGraphContext, PosX - Width / 2,
  1036.         PosY + XFontYOffsetToCenter, Str, Len);
  1037. }
  1038.  
  1039. /*****************************************************************************
  1040. * DESCRIPTION:                                                               M
  1041. * Make some sound.                                                           M
  1042. *                                                                            *
  1043. * PARAMETERS:                                                                M
  1044. *   None                                                                     M
  1045. *                                                                            *
  1046. * RETURN VALUE:                                                              M
  1047. *   void                                                                     M
  1048. *                                                                            *
  1049. * KEYWORDS:                                                                  M
  1050. *   IGIritBeep                                                               M
  1051. *****************************************************************************/
  1052. void IGIritBeep(void)
  1053. {
  1054.     XBell(XDisplay, 0);
  1055. }
  1056.  
  1057. /*****************************************************************************
  1058. * DESCRIPTION:                                                               M
  1059. *   Should we stop this animation. Senses the event queue of X11.            M
  1060. *                                                                            *
  1061. * PARAMETERS:                                                                M
  1062. *   Anim:     The animation to abort.                                        M
  1063. *                                                                            *
  1064. * RETURN VALUE:                                                              M
  1065. *   int:      TRUE if we need to abort, FALSE otherwise.                     M
  1066. *                                                                            *
  1067. * KEYWORDS:                                                                  M
  1068. *   AnimCheckInterrupt                                                       M
  1069. *****************************************************************************/
  1070. int AnimCheckInterrupt(AnimationStruct *Anim)
  1071. {
  1072.     if (XPending(XDisplay)) {
  1073.     Anim -> StopAnim = TRUE;
  1074.     fprintf(stderr, "\nAnimation was interrupted by the user.\n");
  1075.     return TRUE;
  1076.     }
  1077.     else
  1078.         return FALSE;
  1079. }
  1080.